import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;

public class Video {
	static final String AUDIO_PATH = "..\\audio\\";
	static String FFMPEG_PATH = "";
	static File[] files;
	static String FFMPEF_SCRIPT_FILE = "..\\audio\\ff.bat";
	static StringBuilder FFMPEG_SCRIPT;
	static String CONCAT_SCRIPT_FILE = "..\\audio\\join.bat";
	static String CONCAT_LIST_FILE = "..\\audio\\list.txt";

	// static final String logFilePath = "..\\video.txt";

	public static void main(String[] args) {

		try {
			// 1 - LoadProperties
			LoadProperties();
			print("Properties loaded");

			files = getAudioFiles();
			if (Util.isNullObject(files)) {
				System.out.println("Can not get Audio files");
				System.exit(0);
			}

			FFMPEG_SCRIPT = new StringBuilder(100);
			int idx = 1;
			for (File file : files) {

				createVideo(idx);
				idx++;
			}

			writeFFMpegScriptToFile();

			writeVideoListToFile();

			join();

			// 2 - delete files
			// cleanUp();
		} catch (Exception ex) {
			ex.printStackTrace();
		}

	}

	private static void LoadProperties() {
		Properties prop = new Properties();

		try (InputStream input = new FileInputStream("script.properties")) {

			// load properties
			prop.load(input);

			// set property values
			FFMPEG_PATH = prop.getProperty("ffmpeg_path");

		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	private static void createVideo(int idx) throws IOException,
			InterruptedException {

		String _idx = String.valueOf(idx);
		String index;
		if (_idx.length() == 1) {
			index = "0" + _idx;
		} else {
			index = _idx;
		}
		String command = FFMPEG_PATH + "\\ffmpeg -loop 1 -i img-" + index
				+ ".png" + " -i aud-" + index + ".mp3"
				+ " -c:v libx264 -c:a copy -shortest " + "vid-" + index
				+ ".mp4";

		FFMPEG_SCRIPT.append(command + "\n");
		// print(command);
		// Process process = Runtime.getRuntime().exec(command);
		// printProcessOutput(process);
		// print("Generating vid-" + index + ".mp4");
		// process.waitFor();

	}

	private static void join() {
		// ffmpeg -f concat -i mylist.txt -c copy video.mp4
		String script = FFMPEG_PATH
				+ "\\ffmpeg -f concat -i list.txt -c copy video.mp4";
		File scriptFile;

		scriptFile = new File(CONCAT_SCRIPT_FILE);
		if (scriptFile.exists()) {
			scriptFile.delete();
		}

		try (BufferedWriter bw = new BufferedWriter(new FileWriter(scriptFile))) {
			bw.write(script);
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	static void writeVideoListToFile() {
		File file = new File(CONCAT_LIST_FILE);

		if (file.exists()) {
			file.delete();
		}

		StringBuilder fileList = new StringBuilder(100);

		int idx = 1;
		for (File f : files) {
			if (idx < 10) {
				fileList.append("file 'vid-0" + idx + ".mp4'" + "\n");
			} else {
				fileList.append("file 'vid-" + idx + ".mp4'" + "\n");
			}

			idx++;

		}

		try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
			bw.append(fileList);
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	private static void cleanUp() {
		print("Cleaning up...");

		String mp3 = "..\\audio_MP3WRAP.mp3";

		File mp3File = new File(mp3);

		if (!Util.isNullObject(mp3) && mp3File.delete()) {
			print(mp3 + " is deleted");
		}

		// Delete mp3 files from audio folder
		deleteMp3Files(files);

	}

	private static void deleteMp3Files(File[] files) {
		print("Deleting mp3 files");
		File f;
		try {
			for (File file : files) {
				String txt = file.getCanonicalPath();
				String mp3 = txt.replace(".txt", ".mp3");
				f = new File(mp3);
				if (f.exists()) {
					f.delete();
				}
			}
		} catch (IOException ex) {
			System.out.println(ex.toString());
		}
	}

	private static File[] getAudioFiles() {
		// System.out.println("Getting Audio files...");
		File f = new File(AUDIO_PATH); // Captions directory
		// System.out.println("Audio path -> " + f.getAbsolutePath());

		FilenameFilter audioFilter = new FilenameFilter() {
			public boolean accept(File dir, String name) {
				String regEx = "aud-?\\d?\\d?\\.txt";
				return (name.matches(regEx));
			}
		};

		File[] files = f.listFiles(audioFilter);

		return files;
	}

	private static void printProcessOutput(Process p) {
		try (BufferedReader in = new BufferedReader(new InputStreamReader(
				p.getInputStream()))) {

			String line = null;
			while ((line = in.readLine()) != null) {
				System.out.println(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static void print(String msg) {
		System.out.println(msg);
	}

	static void writeFFMpegScriptToFile() {
		File file;

		file = new File(FFMPEF_SCRIPT_FILE);
		if (file.exists()) {
			file.delete();
		}

		try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
			bw.append(FFMPEG_SCRIPT);
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
}
